home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™ 1987-1994 / MacHack™ '87 / Source ƒ.sea / Source ƒ / Pascal ƒ / Transskel.pas ƒ / skel demos / Manywind ƒ / ManyWind.pas next >
Encoding:
Pascal/Delphi Source File  |  1987-01-07  |  7.0 KB  |  268 lines  |  [TEXT/PJMM]

  1. {    ManyWind TransSkel demonstration}
  2.  
  3. {    This application allows up to twenty windows to be created at once,}
  4. {    with the New item under the File menu.  The name of each window}
  5. {    appears under the Windows menu (which is not created until at least}
  6. {    one window exists).  Selecting the window name from the Windows menu}
  7. {    brings the window to the front.  For every window created, Skel is}
  8. {    told to create a new handler.  If the window's close box is clicked,}
  9. {    the handler removes the window name from the Windows menu, disposes}
  10. {    of the window, and removes itself from the window handler list.  If}
  11. {    the window was the last window, the Windows menu handler removes}
  12. {    itself from the menu handler list.}
  13.  
  14. {    When the first window is created, a Color menu also appears.  This}
  15. {    allows the color of the content region of the frontmost window to}
  16. {    be changed.  It goes away when the last window is closed.}
  17.  
  18. {    To quit, select Quit from the File menu or type command-Q.}
  19.  
  20. {    ManyWind demonstrates dynamic window and menu creation and disposal.}
  21. {    It also shows how handler procedures may be shared among handlers}
  22. {    for different windows.}
  23.  
  24. {    The project should include this file, TransSkel.c (or a project}
  25. {    built from TransSkel.c), and MacTraps.}
  26.  
  27. {    28 June 1986        Paul DuBois}
  28. {    7 January 1987 Owen Hartnett, Ωhm Software Co.    }
  29.  
  30. PROGRAM ManyWind;
  31.  
  32.     USES
  33.         TransSkelPas;
  34.  
  35.     CONST
  36.         maxWind = 20;    { maximum number of windows existing at once }
  37.  
  38.                 { menu numbers }
  39.  
  40.         aMenuNum = 1;    { Apple menu }
  41.         fMenuNum = 2;        { File menu }
  42.         wMenuNum = 3;        { Windows menu }
  43.         cMenuNum = 4;        { Color menu }
  44.  
  45.                 { File menu item numbers }
  46.  
  47.         new = 1;
  48.         quit = 3;
  49.  
  50.                 { Color menu items numbers }
  51.  
  52.         cWhite = 1;
  53.         cLtGray = 2;
  54.         cGray = 3;
  55.         cDkGray = 4;
  56.         cBlack = 5;
  57.  
  58.     VAR
  59.         fileMenu, windowMenu, colorMenu : MenuHandle;
  60.  
  61.         windCount : integer;    { number of currently existing windows }
  62.         windNum : longint;    { id of last window created }
  63.  
  64.     PROCEDURE MakeWindow;
  65.     forward;
  66.     PROCEDURE DoWClose;
  67.     forward;
  68.  
  69.     PROCEDURE DoWUpdate;
  70.  
  71.         VAR
  72.             thePort : GrafPtr;
  73.  
  74.     BEGIN
  75.         GetPort(thePort);
  76.         EraseRect(thePort^.portRect);    { repaint w/background pattern }
  77.     END;
  78.  
  79.     PROCEDURE DoMClobber (theMenu : MenuHandle);
  80.  
  81.     BEGIN
  82.         DisposeMenu(theMenu);
  83.     END;
  84.  
  85.     PROCEDURE DoFileMenu (item : integer);
  86.  
  87.     BEGIN
  88.         CASE item OF
  89.             quit : 
  90.                 SkelWhoa;        { tell SkelMain to quit }
  91.             new : 
  92.                 MakeWindow;    { make a new window }
  93.         END;
  94.     END;
  95.  
  96. {    Dispose of window.  Skel makes sure the port is pointing to the}
  97. {    appropriate window, so this procedure can determine which window}
  98. {    is to be disposed, of without being told explicitly.}
  99.  
  100.  
  101.     PROCEDURE DoWClobber;
  102.  
  103.         VAR
  104.             thePort : GrafPtr;
  105.  
  106.     BEGIN
  107.         GetPort(thePort);                { grafport of window to dispose of }
  108.         DisposeWindow(WindowPtr(thePort));
  109.     END;
  110.  
  111. {    Change the background pattern of the frontmost window.  Ignore}
  112. {    if the front window is a DA window.}
  113.  
  114.     PROCEDURE DoColorMenu (item : integer);
  115.  
  116.         VAR
  117.             w : WindowPeek;
  118.             w2 : WindowPtr;
  119.  
  120.     BEGIN
  121.         w := WindowPeek(FrontWindow);
  122.         SetPort(WindowPtr(w));                {*** Fixed bug in original windows    }
  123.         IF w^.windowKind >= 0 THEN             { front is not DA window }
  124.             BEGIN
  125.                 CASE item OF
  126.                     cWhite : 
  127.                         BackPat(white);
  128.                     cLtGray : 
  129.                         BackPat(ltGray);
  130.                     cGray : 
  131.                         BackPat(gray);
  132.                     cDkGray : 
  133.                         BackPat(dkGray);
  134.                     cBlack : 
  135.                         BackPat(black);
  136.                 END;
  137.                 w2 := WindowPtr(w);
  138.                 EraseRect(w2^.portRect);
  139.             END;
  140.     END;
  141.  
  142.  
  143.     PROCEDURE DoWindowMenu (item : integer);
  144.  
  145.         VAR
  146.             iTitle, wTitle : Str255;
  147.             w : WindowPeek;
  148.  
  149.     BEGIN
  150.         GetItem(windowMenu, item, iTitle);     { get window name }
  151.         w := WindowPeek(FrontWindow);
  152.         WHILE w <> NIL DO
  153.             BEGIN
  154.                 GetWTitle(WindowPtr(w), wTitle);
  155.                 IF EqualString(iTitle, wTitle, false, true) THEN
  156.                     BEGIN
  157.                         SelectWindow(WindowPtr(w));
  158.                         w := NIL;
  159.                     END;
  160.                 IF w <> NIL THEN
  161.                     w := w^.nextWindow;
  162.             END;
  163.     END;
  164.  
  165. {    Make new window.  Locate at (100, 100) if no other windows, else}
  166. {    offset slightly from front window.  The window title is the next}
  167. {    window number (1, 2, 3, ...).  If this is the first window, create}
  168. {    the Windows and Color menus.  Add the window title as the last item}
  169. {    of the Windows menu.}
  170.  
  171. {    If the maximum window count has been reached, disable New in the}
  172. {    File menu.}
  173.  
  174.     PROCEDURE MakeWindow;
  175.  
  176.         VAR
  177.             w : WindowPtr;
  178.             r, r2 : Rect;
  179.             s : Str255;
  180.  
  181.     BEGIN
  182.         SetRect(r, 0, 0, 200, 150);
  183.         w := FrontWindow;
  184.         IF w = NIL THEN
  185.             OffsetRect(r, 100, 100)
  186.         ELSE
  187.             BEGIN
  188.                 r2 := w^.portBits.bounds;
  189.                 OffSetRect(r, 20 - r2.left, 20 - r2.top);
  190.                 IF (r.left > 480) OR (r.top > 300) THEN    { keep on screen }
  191.                     OffsetRect(r, 40 - r.left, 40 - r.top);
  192.             END;
  193.         WindNum := windnum + 1;
  194.         NumToString(windNum, s);
  195.         w := NewWindow(NIL, r, s, true, documentProc, WindowPtr(-1), true, 0);
  196.         SkelWindow(w, NIL, NIL, @DoWUpdate, NIL, @DoWClose, @DoWclobber, NIL, false);
  197.         windCount := windCount + 1;
  198.         IF windCount - 1 = 0 THEN     { if first window, create new menus }
  199.             BEGIN
  200.                 colorMenu := NewMenu(cMenuNum, 'Color');
  201.                 AppendMenu(colorMenu, 'White;Light Gray;Gray; Dark Gray; Black');
  202.                 SkelMenu(colorMenu, @DoColorMenu, @DoMClobber);
  203.                 windowMenu := NewMenu(wMenuNum, 'Windows');
  204.                 SkelMenu(windowMenu, @DoWindowMenu, @DoMClobber);
  205.             END;
  206.         AppendMenu(windowMenu, s);
  207.         IF windCount = maxWind THEN
  208.             DisableItem(fileMenu, new);
  209.     END;
  210.  
  211. {    Mouse was clicked in close box.  Remove the window handler (which}
  212. {    causes the window to be disposed of), and delete the window title}
  213. {    from the Windows menu.  If the window was the last one, delete the}
  214. {    Windows and Color menus entirely.}
  215.  
  216. {    Skel makes sure the port is pointing to the appropriate window, so}
  217. {    this procedure can determine which window had its close box clicked,}
  218. {    without being told explicitly.}
  219.  
  220.     PROCEDURE DoWClose;
  221.  
  222.         VAR
  223.             thePort : GrafPtr;
  224.             m : MenuHandle;
  225.             i, mItems : integer;
  226.             iTitle, wTitle : Str255;
  227.  
  228.     BEGIN
  229.         GetPort(thePort);            { grafport of window to be closed }
  230.         GetWTitle(WindowPtr(thePort), wTitle);
  231.         SkelRmveWind(WindowPtr(thePort));
  232.         windCount := windCount - 1;
  233.         IF windCount = 0 THEN
  234.             BEGIN
  235.                 SkelRmveMenu(windowMenu);    { last window - clobber menus }
  236.                 SkelRmveMenu(colorMenu);
  237.             END
  238.         ELSE
  239.             BEGIN    { just take out of menu }
  240.                 m := NewMenu(wMenuNum, 'Windows');
  241.                 mItems := CountMItems(windowMenu);
  242.                 FOR i := 1 TO mItems DO
  243.                     BEGIN
  244.                         GetItem(windowMenu, i, iTitle);
  245.                         IF NOT EqualString(iTitle, wTitle, false, true) THEN
  246.                             AppendMenu(m, iTitle);
  247.                     END;
  248.                 SkelRmveMenu(windowMenu);    { remove old Windows menu }
  249.                 windowMenu := m;                { and install new one }
  250.                 SkelMenu(windowMenu, @DoWindowMenu, @DoMClobber);
  251.             END;
  252.         EnableItem(fileMenu, new);    { can always create at least one more now }
  253.     END;
  254.  
  255.  
  256. BEGIN
  257.  
  258.     WindCount := 0;
  259.     WindNum := 0;
  260.     SkelInit;                                            { initialize }
  261.     SkelApple('', NIL);                                { handle desk accessories }
  262.     fileMenu := NewMenu(fMenuNum, 'File');        { make File menu handler }
  263.     AppendMenu(fileMenu, 'New/N;(-;Quit/Q');
  264.     SkelGrowBounds(NIL, 50, 10, 500, 300);
  265.     SkelMenu(fileMenu, @DoFileMenu, @DoMClobber);
  266.     SkelMain;                                        { loop 'til Quit selected }
  267.     SkelClobber;                                    { clean up }
  268. END.